package com.sinosoft.comm.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.sinosoft.comm.condition.BaseCondition;
import com.sinosoft.comm.entity.BaseEntity;
import com.sinosoft.comm.enums.DelFlagEnum;
import com.sinosoft.comm.service.BaseService;

import com.sinosoft.utils.classzz.ClassUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import tk.mybatis.mapper.common.Mapper;
import tk.mybatis.mapper.entity.Example;
import tk.mybatis.mapper.entity.Example.Criteria;

import java.io.Serializable;
import java.lang.reflect.Field;
import java.util.Date;
import java.util.List;


public class BaseServiceImpl<T extends BaseEntity, F extends BaseCondition> implements BaseService<T, F> {
	@Autowired
	protected Mapper<T> mapper;
	private Class<T> entityClass;


	@SuppressWarnings("unchecked")
	public BaseServiceImpl() {
			entityClass = (Class<T>) ClassUtil.getSuperClassGenricType(getClass());
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED)
	public T save(T entity){
		if (entity.getDelFlag() == null) {
			 entity.setDelFlag(DelFlagEnum.YES.getDelFlag());
		}
		if (entity.getId() != null && entity.getId().trim().length()> 0) {
				entity.setUpdateTime(new Date());
			mapper.updateByPrimaryKeySelective(entity);
		} else {
				entity.setCreateTime(new Date());
				entity.setUpdateTime(new Date());
				entity.setId(createPrimaryKey());
				mapper.insert(entity);
		}
		return this.getById(entity.getId());
	}

	@Override
	public T getById(Serializable id) {
		return mapper.selectByPrimaryKey(id);
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED)
	public int deleteById(Serializable id) {
		return mapper.deleteByPrimaryKey(id);
	}

	@Override
	public List<T> selectPage(F filter) {
		Example example = new Example(entityClass);
		int pageNum = filter.getPage();// (Integer) ClassUtil.getFiledValue(filter, "page");
		// System.out.println("pageNum:"+pageNum);
		int pageSize = filter.getRows();// (Integer) ClassUtil.getFiledValue(filter, "rows");
		// System.out.println("pageSize:"+pageSize);
		Criteria criteria = example.createCriteria();
		genCriteria(filter, criteria);
		example.setOrderByClause(filter.getOrderbyField());
		PageHelper.startPage(pageNum, pageSize);
		List<T> list = mapper.selectByExample(example);
		return list;
	}
	@Override
	public PageInfo<T> getPageList(F filter) {
		List<T> pageList = null;
		pageList = selectPage(filter);
		PageInfo<T> pageInfo = new PageInfo<T>(pageList);
		return pageInfo;
	}
	@Override
	public List<T> selectAll(F filter) {
		Example example = new Example(entityClass);
		Criteria criteria = example.createCriteria();
		genCriteria(filter, criteria);
		example.setOrderByClause(filter.getOrderbyField());
		List<T> list = mapper.selectByExample(example);
		return list;
	}

	@Transactional(propagation = Propagation.REQUIRED)
	@Override
	public int updateByFilter(T entity, F filter) {
		Example example = new Example(entity.getClass());
		Criteria criteria = example.createCriteria();
		genCriteria(filter, criteria);
		return mapper.updateByExampleSelective(entity, example);
	}

	private void genCriteria(F filter, Criteria criteria) {
		for (Field filed : ClassUtil.getField(filter)) {
			Object obj = ClassUtil.getFiledValue(filter, filed.getName());
			if (!StringUtils.isEmpty(obj.toString())) {
				String strs[] = filed.getName().split("_");
				if (strs.length == 2) {
					String filedStr = strs[1].toString();
					if ("eq".equals(strs[0].toLowerCase()) && !"".equals(obj.toString())) {
						criteria.andEqualTo(filedStr, obj);
						continue;
					} else if ("lk".equals(strs[0].toLowerCase())) {
						criteria.andLike(filedStr, "%" + obj + "%");
						continue;
					} else if ("llk".equals(strs[0].toLowerCase())) {
						criteria.andLike(filedStr, "%" + obj);
						continue;
					} else if ("rlk".equals(strs[0].toLowerCase())) {
						criteria.andLike(filedStr, obj + "%");
						continue;
					}
					else if ("eqlk".equals(strs[0].toLowerCase())) {
						criteria.andLike(filedStr, obj+"");
						continue;
					}
					// 大于
					else if ("gt".equals(strs[0].toLowerCase())) {
						criteria.andGreaterThan(filedStr, obj);
						continue;
					}
					// 小于
					else if ("lt".equals(strs[0].toLowerCase())) {
						criteria.andLessThan(filedStr, obj);
						continue;
					}
					// 大于等于
					else if ("ge".equals(strs[0].toLowerCase())) {
						criteria.andGreaterThanOrEqualTo(filedStr, obj);
						continue;
					}
					// 小于等于
					else if ("le".equals(strs[0].toLowerCase())) {
						criteria.andLessThanOrEqualTo(filedStr, obj);
						continue;
					} else if ("in".equals(strs[0].toLowerCase())) {
						criteria.andIn(filedStr, (List<?>) obj);
						continue;
					} else if ("null".equals(strs[0].toLowerCase())) {
						if (obj != null && obj.equals(true)) {
							criteria.andIsNull(filedStr);
						} else if (obj != null && obj.equals(false)) {
							criteria.andIsNotNull(filedStr);
						}
						continue;
					}

				}
			}
		}
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED)
	public int deleteByFilter(F filter) {
		Example example = new Example(entityClass);
		Criteria criteria = example.createCriteria();
		genCriteria(filter, criteria);
		return mapper.deleteByExample(example);
	}

	@Override
	public List<T> selectAll() {
		return this.selectAll(initFilter());
	}

	public Mapper<T> getMapper() {
		return mapper;
	}

	@Override
	public int selectCountByFilter(F filter) {
		Example example = new Example(entityClass);
		Criteria criteria = example.createCriteria();
		genCriteria(filter, criteria);
		return mapper.selectCountByExample(example);
	}

	
	@Override
	@Transactional(propagation = Propagation.REQUIRED)
	public int delAll(List<String> idList) {
		F filter=initFilter();
		if (idList == null || idList.size() < 1) {
			return -1;
		}
		filter.setIn_id(idList);
		T entity = null;
		try {
			entity = entityClass.newInstance();
		} catch (Exception e) {
			e.printStackTrace();
			return -1;
		}
		entity.setDelFlag(DelFlagEnum.NO.getDelFlag());
		return updateByFilter(entity, filter);

	}

	@SuppressWarnings("unchecked")
	private F initFilter() {
		try {
			return  (F) ClassUtil.getSuperClassGenricType(getClass(), 1).newInstance();
		} catch (InstantiationException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		} catch (IllegalAccessException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		return null;
	}

}
